#include <iostream>
#include <functional>
#include <unordered_map>
#include "codec.h"
#include "dispatcher.h"

#include "muduo/net/EventLoop.h"
#include "muduo/net/TcpServer.h"
#include "response.pb.h"

#include "unistd.h"
using namespace rbmq;
using namespace std;

class Server
{
    typedef std::shared_ptr<rbmq::TranslateRequest> TranslateRequestPtr;
    typedef std::shared_ptr<rbmq::AddRequest> AddRequestPtr;

public:
    Server(int port)
        : _server(&_baseloop, muduo::net::InetAddress( port), "Server", muduo::net::TcpServer::kReusePort),
          _dispatcher(std::bind(&Server::onUnknownMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
          _codec(std::bind(&ProtobufDispatcher::onProtobufMessage, &_dispatcher, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))
    {
        // 为派发器注册方法
        _dispatcher.registerMessageCallback<rbmq::TranslateRequest>(std::bind(&Server::OnTranslate, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        _dispatcher.registerMessageCallback<rbmq::AddRequest>(std::bind(&Server::OnAdd, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

        // 为服务器绑定方法
        _server.setConnectionCallback(std::bind(&Server::OnConnection, this, std::placeholders::_1));
        _server.setMessageCallback(std::bind(&ProtobufCodec::onMessage, &_codec, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }
    void Start()
    {
        _server.start();
        _baseloop.loop();
    }

private:
    void onUnknownMessage(const muduo::net::TcpConnectionPtr &conn, const MessagePtr &message, muduo::Timestamp)
    {
        std::cout << "onUnknownMessage: " << message->GetTypeName();
        conn->shutdown();
    }
    void OnConnection(const muduo::net::TcpConnectionPtr &conn)
    {
        if (conn->connected())
            cout << "建立连接" << endl;
        else
            cout << "断开连接";
    }

    static std::string translate(const std::string word)
    {
        std::unordered_map<std::string, std::string> dict{
            {"word", "单词"}, {"listen", "监听"}, {"message", "消息"}, {"apple", "苹果"}};

        auto iter = dict.find(word);
        if (iter != dict.end())
            return iter->second; // 找到翻译则立即返回

        return "没找到!";
    }

    // translate业务的回调
    void OnTranslate(const muduo::net::TcpConnectionPtr &conn, const TranslateRequestPtr &message, muduo::Timestamp t)
    {
        // 获取请求
        std::string req_meg = message->word();
        // 处理业务
        std::string resp_msg = translate(req_meg);
        rbmq::TranslateResponse resp;
        resp.set_trans(resp_msg);
        _codec.send(conn, resp);
    }

    // add业务的回调
    void OnAdd(const muduo::net::TcpConnectionPtr &conn, const AddRequestPtr &message, muduo::Timestamp t)
    {
        int num1 = message->num1();
        int num2 = message->num2();
        int ret=num1+num2;
        rbmq::AddResponse resp;
        resp.set_ret(ret);
        _codec.send(conn, resp);
    }

private:
    muduo::net::EventLoop _baseloop;
    muduo::net::TcpServer _server;
    ProtobufDispatcher _dispatcher;
    ProtobufCodec _codec;
};

int main()
{
    Server svr(8088);
    svr.Start();
    return 0;
}
